using System;
using System.Reflection;
using System.Text;
using PropertyExpression.Common;

namespace PropertyExpression.PresentationCode.CodeGenerator
{
    internal class SimplePropertyExtensionsGenerator : IExtensionsGenerator
    {
        private readonly Type type;
        private readonly Type targetType;

        public SimplePropertyExtensionsGenerator(Type type, Type targetType)
        {
            this.type = type;
            this.targetType = targetType;
        }

        public IOptionalResult<IOverloadedAndPrefixMethodsBuilder> BuildAttachedProperty(string propertyName, StringBuilder builder, MethodInfo methodInfo,
                                                                                         Type parameterType, Type attachedMethodTargetType, FieldInfo fieldInfo)
        {
            return Build(propertyName, builder, parameterType, fieldInfo);
        }

        public IOptionalResult<IOverloadedAndPrefixMethodsBuilder> BuildSimpleProperty(
            string propertyName, StringBuilder builder, FieldInfo fieldInfo, Type parameterType)
        {
            return Build(propertyName, builder, parameterType, fieldInfo);
        }

        private IOptionalResult<IOverloadedAndPrefixMethodsBuilder> Build(string propertyName, StringBuilder builder, Type parameterType, FieldInfo fieldInfo)
        {
            var methodName = string.Format("{0}_{1}", type.Name, propertyName);
            builder.AppendFormat(
                @"        public static {4} {0}(this {4} it,  {1} value)
        {{
            return it.SetValue({2}.{3}, value);
        }}
",
                methodName,
                InternalUtil.GetCSharTypeName(parameterType),
                type,
                fieldInfo.Name,
                targetType);

            return new SimplePropertyOverloadedAndPrefixMethodsBuilder(methodName, targetType)
                .AsOptionalResult<IOverloadedAndPrefixMethodsBuilder>();
        }
    }
}